with Interfaces.C; use Interfaces.C;
with data_library; use data_library;
with buses;        use buses;
with bus_stops;    use bus_stops;
with Ada.text_io;  use Ada.text_io;
with Ada.Integer_Text_Io; use Ada.Integer_Text_Io;
with interface_cpp;use interface_cpp;
with Ada.Strings; use Ada.Strings;

package body gestionnaire is
    
    -- type pointeur de bus
    type bus_ptr is Access bus;
    
        
    -- type pointeur de bus_stop
    type bus_stop_ptr is Access bus_stop;
    
    -- nombre de bus cree
    Nb_bus      : Integer ;
    
    Nb_bus_stop : constant Integer := 20;
    
    task body controleur is
    busLinesList : bus_line_list(20);
    choix : integer;

	-- Creation des lignes de bus
        it1 : bus_Line(8);
	it2 : bus_Line(8);
	it3 : bus_Line(8);
	it4 : bus_Line(8);
	it5 : bus_Line(8);
	it6 : bus_Line(8);
	it7 : bus_Line(8);
	it8 : bus_Line(8);
	it9 : bus_Line(8);
	it10 : bus_Line(8);

        --Specification de la fonction permettant de recuperer l'indice d'un bus stop à partir de son ID
        function getIndiceFromIDBus_Stop(id : integer) return integer;
        
        -- Creation des bus stop
        type T_tab_instance_bus_stop is array (natural range <>) of bus_stop_ptr; 
        tab_instance_bus_stop: T_tab_instance_bus_stop (1..Nb_bus_stop);  -- Tableau des instances de bus_stop
        
        -- Structure pour creer une ligne de bus
        Struct_bs1:data_library.T_bus_Stop := (1,true, 0.2); -- 0.2 km = 200 m
        Struct_bs2:data_library.T_bus_Stop := (2,true, 0.3); -- 0.3 km = 300 m
        Struct_bs3:data_library.T_bus_Stop := (3,true, 0.4); -- 0.4 km = 100 m
        Struct_bs4:data_library.T_bus_Stop := (4,true, 0.3);
        Struct_bs5:data_library.T_bus_Stop := (5,true, 0.5);
        Struct_bs6:data_library.T_bus_Stop := (6,true, 0.4);
        Struct_bs7:data_library.T_bus_Stop := (7,true, 0.2);
        Struct_bs8:data_library.T_bus_Stop := (8,true, 0.4);
        Struct_bs9:data_library.T_bus_Stop := (9,true, 0.4);
        Struct_bs10:data_library.T_bus_Stop := (10,true, 0.0);
        Struct_bs11:data_library.T_bus_Stop := (11,true, 0.5);
        Struct_bs12:data_library.T_bus_Stop := (12,true, 0.4);
        Struct_bs13:data_library.T_bus_Stop := (13,true, 0.5);
        Struct_bs14:data_library.T_bus_Stop := (14,true, 0.3);
        Struct_bs15:data_library.T_bus_Stop := (15,true, 0.5);
        Struct_bs16:data_library.T_bus_Stop := (16,true, 0.4);
        Struct_bs17:data_library.T_bus_Stop := (17,true, 0.3);
        Struct_bs18:data_library.T_bus_Stop := (18,true, 0.4);
        Struct_bs19:data_library.T_bus_Stop := (19,true, 0.3);
        Struct_bs20:data_library.T_bus_Stop := (20,true, 0.0);
        
        -- Creation d'un bus
        type T_tab_instance_bus is array (natural range <>) of bus_ptr; 
        tab_instance_bus: T_tab_instance_bus (1..100); 

        
        --Corps de la fonction permettant de recuperer l'indice d'un bus stop à partir de son ID
        function getIndiceFromIDBus_Stop(id : integer) return integer is
                idtmp : integer;
                i : integer;
        begin
                i:=1;
                while (i<=tab_instance_bus_stop'length)
                loop
                    tab_instance_bus_stop(i).all.getId(idtmp);
                    if (idtmp=id) then
                        return i;
                    end if;
                    i:=i+1;
                end loop;
                put_line("Erreur: numero de bus stop inconnu!");
                return -1; 
                Exception
                    when others =>
                        put_line("Exception fonction getIndiceFromIDBus_Stop!");  
                        return -2;   
          end getIndiceFromIDBus_Stop;
          
          --Fonction recuperant une ligne de bus par son ID
          function getBusLineFromId(id : in integer) return bus_Line is
         tmp : bus_line;
         begin
       if (busLinesList.Sommet/=0)
		then
		for i in  1..busLinesList.Sommet
		loop
		if (busLinesList.TabBL(i).idLine=id)
		then
		return busLinesList.TabBL(i);
		end if;
		end loop;
		end if;
		return tmp;
          end getBusLineFromId;
          
          
          procedure displayBusLinesList is
          begin
          put_line("=========================================================");
put_line("=========================================================");
put_line("===================URBAN BUS NETWORK=====================");
put_line("=========================================================");
put_line("=========================================================");
put_line("");
          put_line("=========================================================");
put_line("=                LISTE DES LIGNES DE BUS                =");
put_line("=========================================================");
put_line("  Numero Ligne  |            Liste des arrets");
put_line("---------------------------------------------------------");
if (busLinesList.Sommet/=0)
then
for i in  1..busLinesList.Sommet
loop
if (busLinesList.TabBL(i).idLine<10)
then
Ada.text_io.put("      "&Integer'image(busLinesList.TabBL(i).idLine)&"        |    ");
else
Ada.text_io.put("      "&Integer'image(busLinesList.TabBL(i).idLine)&"       |    ");
end if;
if (busLinesList.TabBL(i).Sommet/=0)
then
for j in  1..busLinesList.TabBL(i).Sommet
loop 
Ada.text_io.put(Integer'image(busLinesList.TabBL(i).TabBS(j).idBusStop));
if (j/=busLinesList.TabBL(i).Sommet)
then
Ada.text_io.put(",");
end if;
end loop;
end if;
put_line("");
end loop;
end if;
put_line("=========================================================");
end displayBusLinesList;
        

    begin
        

	        
        -- Initialisation de la ligne numero 1
        it1.idLine  := 1;
        it1.Sommet:=it1.Sommet+1;
        it1.TabBS(it1.Sommet):= Struct_bs1;
        it1.Sommet:=it1.Sommet+1;
        it1.TabBS(it1.Sommet):= Struct_bs2; 
        it1.Sommet:=it1.Sommet+1;
        it1.TabBS(it1.Sommet):= Struct_bs3;
        it1.Sommet:=it1.Sommet+1;
        it1.TabBS(it1.Sommet):= Struct_bs4; 
        it1.Sommet:=it1.Sommet+1;
        it1.TabBS(it1.Sommet):= Struct_bs5; 
        it1.Sommet:=it1.Sommet+1;
        it1.TabBS(it1.Sommet):= Struct_bs6; 
        it1.Sommet:=it1.Sommet+1;
        it1.TabBS(it1.Sommet):= Struct_bs7; 
        it1.Sommet:=it1.Sommet+1;
        it1.TabBS(it1.Sommet):= Struct_bs10; 

        busLinesList.Sommet:=busLinesList.Sommet+1;
        busLinesList.TabBL(busLinesList.Sommet):=it1;

      it2.idLine  := 2;
        it2.Sommet:=it2.Sommet+1;
        it2.TabBS(it2.Sommet):= Struct_bs2;
        it2.Sommet:=it2.Sommet+1;
        it2.TabBS(it2.Sommet):= Struct_bs4; 
        it2.Sommet:=it2.Sommet+1;
        it2.TabBS(it2.Sommet):= Struct_bs6;
        it2.Sommet:=it2.Sommet+1;
        it2.TabBS(it2.Sommet):= Struct_bs8; 
        it2.Sommet:=it2.Sommet+1;
        it2.TabBS(it2.Sommet):= Struct_bs11; 
        it2.Sommet:=it2.Sommet+1;
        it2.TabBS(it2.Sommet):= Struct_bs12; 
        it2.Sommet:=it2.Sommet+1;
        it2.TabBS(it2.Sommet):= Struct_bs13; 
        it2.Sommet:=it2.Sommet+1;
        it2.TabBS(it2.Sommet):= Struct_bs20; 

        busLinesList.Sommet:=busLinesList.Sommet+1;
        busLinesList.TabBL(busLinesList.Sommet):=it2;

      it3.idLine  := 3;
        it3.Sommet:=it3.Sommet+1;
        it3.TabBS(it3.Sommet):= Struct_bs3;
        it3.Sommet:=it3.Sommet+1;
        it3.TabBS(it3.Sommet):= Struct_bs5; 
        it3.Sommet:=it3.Sommet+1;
        it3.TabBS(it3.Sommet):= Struct_bs7;
        it3.Sommet:=it3.Sommet+1;
        it3.TabBS(it3.Sommet):= Struct_bs8; 
        it3.Sommet:=it3.Sommet+1;
        it3.TabBS(it3.Sommet):= Struct_bs9; 
        it3.Sommet:=it3.Sommet+1;
        it3.TabBS(it3.Sommet):= Struct_bs11; 
        it3.Sommet:=it3.Sommet+1;
        it3.TabBS(it3.Sommet):= Struct_bs12; 
        it3.Sommet:=it3.Sommet+1;
        it3.TabBS(it3.Sommet):= Struct_bs10; 

        busLinesList.Sommet:=busLinesList.Sommet+1;
        busLinesList.TabBL(busLinesList.Sommet):=it3;

      it4.idLine  := 4;
        it4.Sommet:=it4.Sommet+1;
        it4.TabBS(it4.Sommet):= Struct_bs1;
        it4.Sommet:=it4.Sommet+1;
        it4.TabBS(it4.Sommet):= Struct_bs2; 
        it4.Sommet:=it4.Sommet+1;
        it4.TabBS(it4.Sommet):= Struct_bs5;
        it4.Sommet:=it4.Sommet+1;
        it4.TabBS(it4.Sommet):= Struct_bs6; 
        it4.Sommet:=it4.Sommet+1;
        it4.TabBS(it4.Sommet):= Struct_bs9; 
        it4.Sommet:=it4.Sommet+1;
        it4.TabBS(it4.Sommet):= Struct_bs13; 
        it4.Sommet:=it4.Sommet+1;
        it4.TabBS(it4.Sommet):= Struct_bs17; 
        it4.Sommet:=it4.Sommet+1;
        it4.TabBS(it4.Sommet):= Struct_bs20; 

        busLinesList.Sommet:=busLinesList.Sommet+1;
        busLinesList.TabBL(busLinesList.Sommet):=it4;

      it5.idLine  := 5;
        it5.Sommet:=it5.Sommet+1;
        it5.TabBS(it5.Sommet):= Struct_bs6;
        it5.Sommet:=it5.Sommet+1;
        it5.TabBS(it5.Sommet):= Struct_bs7; 
        it5.Sommet:=it5.Sommet+1;
        it5.TabBS(it5.Sommet):= Struct_bs14;
        it5.Sommet:=it5.Sommet+1;
        it5.TabBS(it5.Sommet):= Struct_bs15; 
        it5.Sommet:=it5.Sommet+1;
        it5.TabBS(it5.Sommet):= Struct_bs16; 
        it5.Sommet:=it5.Sommet+1;
        it5.TabBS(it5.Sommet):= Struct_bs17; 
        it5.Sommet:=it5.Sommet+1;
        it5.TabBS(it5.Sommet):= Struct_bs18; 
        it5.Sommet:=it5.Sommet+1;
        it5.TabBS(it5.Sommet):= Struct_bs20; 

        busLinesList.Sommet:=busLinesList.Sommet+1;
        busLinesList.TabBL(busLinesList.Sommet):=it5;

      it6.idLine  := 6;
        it6.Sommet:=it6.Sommet+1;
        it6.TabBS(it6.Sommet):= Struct_bs12;
        it6.Sommet:=it6.Sommet+1;
        it6.TabBS(it6.Sommet):= Struct_bs13; 
        it6.Sommet:=it6.Sommet+1;
        it6.TabBS(it6.Sommet):= Struct_bs14;
        it6.Sommet:=it6.Sommet+1;
        it6.TabBS(it6.Sommet):= Struct_bs15; 
        it6.Sommet:=it6.Sommet+1;
        it6.TabBS(it6.Sommet):= Struct_bs16; 
        it6.Sommet:=it6.Sommet+1;
        it6.TabBS(it6.Sommet):= Struct_bs17; 
        it6.Sommet:=it6.Sommet+1;
        it6.TabBS(it6.Sommet):= Struct_bs19; 
        it6.Sommet:=it6.Sommet+1;
        it6.TabBS(it6.Sommet):= Struct_bs20; 

        busLinesList.Sommet:=busLinesList.Sommet+1;
        busLinesList.TabBL(busLinesList.Sommet):=it6;

      it7.idLine  := 7;
        it7.Sommet:=it7.Sommet+1;
        it7.TabBS(it7.Sommet):= Struct_bs7;
        it7.Sommet:=it7.Sommet+1;
        it7.TabBS(it7.Sommet):= Struct_bs9; 
        it7.Sommet:=it7.Sommet+1;
        it7.TabBS(it7.Sommet):= Struct_bs11;
        it7.Sommet:=it7.Sommet+1;
        it7.TabBS(it7.Sommet):= Struct_bs16; 
        it7.Sommet:=it7.Sommet+1;
        it7.TabBS(it7.Sommet):= Struct_bs17; 
        it7.Sommet:=it7.Sommet+1;
        it7.TabBS(it7.Sommet):= Struct_bs18; 
        it7.Sommet:=it7.Sommet+1;
        it7.TabBS(it7.Sommet):= Struct_bs19; 
        it7.Sommet:=it7.Sommet+1;
        it7.TabBS(it7.Sommet):= Struct_bs20; 

        busLinesList.Sommet:=busLinesList.Sommet+1;
        busLinesList.TabBL(busLinesList.Sommet):=it7;

      it8.idLine  := 8;
        it8.Sommet:=it8.Sommet+1;
        it8.TabBS(it8.Sommet):= Struct_bs5;
        it8.Sommet:=it8.Sommet+1;
        it8.TabBS(it8.Sommet):= Struct_bs6; 
        it8.Sommet:=it8.Sommet+1;
        it8.TabBS(it8.Sommet):= Struct_bs9;
        it8.Sommet:=it8.Sommet+1;
        it8.TabBS(it8.Sommet):= Struct_bs13; 
        it8.Sommet:=it8.Sommet+1;
        it8.TabBS(it8.Sommet):= Struct_bs17; 
        it8.Sommet:=it8.Sommet+1;
        it8.TabBS(it8.Sommet):= Struct_bs18; 
        it8.Sommet:=it8.Sommet+1;
        it8.TabBS(it8.Sommet):= Struct_bs19; 
        it8.Sommet:=it8.Sommet+1;
        it8.TabBS(it8.Sommet):= Struct_bs20; 

        busLinesList.Sommet:=busLinesList.Sommet+1;
        busLinesList.TabBL(busLinesList.Sommet):=it8;

      it9.idLine  := 9;
        it9.Sommet:=it9.Sommet+1;
        it9.TabBS(it9.Sommet):= Struct_bs2;
        it9.Sommet:=it9.Sommet+1;
        it9.TabBS(it9.Sommet):= Struct_bs5; 
        it9.Sommet:=it9.Sommet+1;
        it9.TabBS(it9.Sommet):= Struct_bs6;
        it9.Sommet:=it9.Sommet+1;
        it9.TabBS(it9.Sommet):= Struct_bs8; 
        it9.Sommet:=it9.Sommet+1;
        it9.TabBS(it9.Sommet):= Struct_bs9; 
        it9.Sommet:=it9.Sommet+1;
        it9.TabBS(it9.Sommet):= Struct_bs13; 
        it9.Sommet:=it9.Sommet+1;
        it9.TabBS(it9.Sommet):= Struct_bs15; 
        it9.Sommet:=it9.Sommet+1;
        it9.TabBS(it9.Sommet):= Struct_bs20; 

        busLinesList.Sommet:=busLinesList.Sommet+1;
        busLinesList.TabBL(busLinesList.Sommet):=it9;

      it10.idLine  := 10;
        it10.Sommet:=it10.Sommet+1;
        it10.TabBS(it10.Sommet):= Struct_bs3;
        it10.Sommet:=it10.Sommet+1;
        it10.TabBS(it10.Sommet):= Struct_bs4; 
        it10.Sommet:=it10.Sommet+1;
        it10.TabBS(it10.Sommet):= Struct_bs8;
        it10.Sommet:=it10.Sommet+1;
        it10.TabBS(it10.Sommet):= Struct_bs9; 
        it10.Sommet:=it10.Sommet+1;
        it10.TabBS(it10.Sommet):= Struct_bs13; 
        it10.Sommet:=it10.Sommet+1;
        it10.TabBS(it10.Sommet):= Struct_bs16; 
        it10.Sommet:=it10.Sommet+1;
        it10.TabBS(it10.Sommet):= Struct_bs19; 
        it10.Sommet:=it10.Sommet+1;
        it10.TabBS(it10.Sommet):= Struct_bs20; 

        busLinesList.Sommet:=busLinesList.Sommet+1;
        busLinesList.TabBL(busLinesList.Sommet):=it10;

      
	-- Creation des bus_stop
	for i in 1..Nb_bus_stop
        loop
            tab_instance_bus_stop(i) := new bus_stop;
            tab_instance_bus_stop(i).create(i);
        end loop;

--Interface de demarrage
--Effacage de l'ecran
put(Character'Val (27) & "[2J");
displayBusLinesList;
put("Entrez le nombre total de bus : ");
get(Nb_bus);
        -- Creation de l'Operating center
        create_operating_center(Nb_bus);
put_line("=========================================================");
put_line("===================Affectation des bus=====================");
put_line("=========================================================");
        -- Creation des bus
        for i in 1..Nb_bus
        loop       
        put_line("Affecter le bus "&Integer'Image(i)&" a la ligne  : ");
        get(choix);
            tab_instance_bus(i) := new bus;
            tab_instance_bus(i).create(i,getBusLineFromId(choix)); 
        end loop;
        put(Character'Val (27) & "[2J");
        displayBusLinesList;
        put_line("");
        put_line("");
        put_line("");
        put_line("Ouvrez le fichier index.html pour voir le suivi des bus...");
        loop
            select
                accept set_bus_arrival_time(numBusStop: in Integer;s : in ptr_T_Schedule) do
                    tab_instance_bus_stop(getIndiceFromIDBus_Stop(numBusStop)).set_arrival_time(s);
                end;
            or    
                accept set_bus_time(numBus: in Integer; retard: in Integer) do
                    tab_instance_bus(numBus).set_bus_time(retard);
                end;
            or              
    	        accept deviation(numBus: in integer) do
    		       tab_instance_bus(numBus).deviation(numBus);
    	        end deviation;
            end select;
        end loop;
        Exception
            when others =>
        put_line("Exception tache controlleur!");
    end controleur;
end gestionnaire;
